{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "fe98a9e5-4646-47d0-9445-19bf22ef3a54",
   "metadata": {},
   "source": [
    "# <center>Ch5 RLHF详解 </center>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a775fdc5",
   "metadata": {},
   "source": [
    "# 1.RLHF背景和意义"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "347edff5",
   "metadata": {},
   "source": [
    "**没有 RLHF 就没有今天的 ChatGPT**。RLHF 是ChatGPT背后最关键的技术之一，它使得模型更好地理解和满足用户需求，提升用户体验。这对OpenAI的成功至关重要，从技术和商业两个方面来看，RLHF带来的价值极其巨大。 \n",
    "**2022年底 ChatGPT 的发布** 是RLHF爆红的标志性事件：  <br>\n",
    "\n",
    "**ChatGPT 一炮而红**：  <br>\n",
    "  - 发布后 **5天内用户数破100万**，成为历史上增长最快的互联网产品之一。  <br>\n",
    "  - 仅用 **两个月** 达到 1 亿月活用户，这种增长速度比抖音、Instagram 等顶级应用快得多。对于一家技术型公司而非娱乐公司，这一现象打破了所有历史的巅峰。<br>\n",
    "  - 这背后的关键技术之一正是 **RLHF**。  <br>\n",
    "\n",
    "- **RLHF 的收益评估**  <br>\n",
    "- **直接营收估算**  <br>\n",
    "   - 据报道，截至2024年ChatGPT每月用户量接近1.8亿，其中订阅用户数占比可观。即使只有5%的用户订阅Plus，每月也有 **$1.8亿（1.8 亿用户 × 5% × $20）** 的订阅收入。RLHF可以说贡献了其中大部分收入。  <br>\n",
    "- **估值增长**  <br>\n",
    "   - OpenAI 的估值从几年前的数十亿美元攀升至如今的 **900 亿美元以上**，RLHF 的独特性是其估值增长的重要因素之一。  <br>\n",
    "\n",
    "**资本和企业竞相追逐**  <br>\n",
    "- 全球涌现了大量创业公司，专注于将 RLHF 应用于特定场景（如个性化助手、医疗、教育等）。  <br>\n",
    "- 投资界对大模型相关项目的关注空前，RLHF 的热度直接推动了数百亿美金的融资。<br>\n",
    "**RLHF 就像“风口上的猪”，凡是搭上这股技术浪潮的公司，估值都在暴涨，创业者和资本都争先恐后地涌入。**<br>\n",
    "\n",
    "**RLHF之于OpenAI，犹如iPhone之于Apple**\n",
    "- iPhone 不是 Apple 的第一款产品，但它彻底改变了 Apple 的命运，让它成为消费电子领域的领导者。同样，RLHF让OpenAI从一家以研究为主的实验室，转变为一家具有巨大战略价值和商业影响力的公司。<br>\n",
    "- iPhone 重新定义了手机，RLHF 重新定义了 AI 的人机交互体验。<br>\n",
    "\n",
    "**RLHF 就像科技圈的 “世界杯”，每次新研究或新模型发布，都能掀起行业内外的热烈讨论。**\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "321f0107",
   "metadata": {},
   "source": [
    "## 什么是RLHF"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a2d89656",
   "metadata": {},
   "source": [
    "RLHF（Reinforcement Learning with Human Feedback，基于人类反馈的强化学习）是一种结合**强化学习**和**人类反馈**的方法，用来训练人工智能模型，使其行为更符合人类的需求和偏好。\n",
    "- 它的核心目标是解决模型输出不够贴近人类需求的问题，让 AI 不仅能“回答问题”，还能“回答得好、回答得安全”。\n",
    "\n",
    "简单讲：RLHF 就是通过人类告诉 AI 什么是“好答案”，然后让 AI 学会用强化学习的方法优化自己，生成更符合人类期望的内容。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9ace2a5f",
   "metadata": {},
   "source": [
    "## 一定需要RLHF么？"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "38b149b3",
   "metadata": {},
   "source": [
    "**先说一下需要RLHF的主要原因是为了让人工智能模型的输出更符合人类的需求和偏好，解决传统机器学习方法中的一些核心问题。** \n",
    "```json\n",
    "1、解决预定义奖励函数的局限性\n",
    "    奖励函数难以设计：很多现实任务（如对话、内容生成）中，无法用简单的公式或规则量化“好”或“坏”。  \n",
    "        例如：什么样的文章是“好”的？什么样的回答是“贴心”的？这些都很主观。  \n",
    "    奖励信号不明确：在一些复杂场景中（如聊天机器人），模型很难通过环境的直接反馈（如用户点击）学习出明确的优化方向。 \n",
    "  通过人类反馈代替直接奖励函数，训练出奖励模型，让AI学会符合人类偏好的行为，弥补了预定义奖励函数的不足。  \n",
    "\n",
    "2、优化模型的“人性化”表现\n",
    "    缺乏语境理解：无法准确理解用户的意图。  \n",
    "    表现不自然：回答生硬、不礼貌，缺乏“人情味”。  \n",
    "    过于自信或偏离主题：模型可能对错误答案表现得非常自信，一本正经的胡说八道。  \n",
    "\n",
    "3、提高内容安全性  \n",
    "    有害内容：例如歧视性语言、不当言论。  \n",
    "    危险建议：如非法操作、医学错误。  \n",
    "    偏见问题：受训练数据的限制，可能输出带有偏见的答案。  \n",
    "\n",
    "5、个性化与定制化需求\n",
    "  专业用户：希望回答技术性强且准确。  \n",
    "  普通用户：希望回答通俗易懂、易于接受。  \n",
    "  特定领域：如法律、医学等领域的用户，需要模型能针对性地生成内容。  \n",
    "\n",
    "  通过人类的多维度反馈，模型能够逐步学习如何在多个目标之间找到最佳平衡点，实现综合性能的提升。 \n",
    "    假设你是一位老师，正在教一个学生（AI 模型）写作文：  \n",
    "    1、预训练模型就像这个学生从图书馆借来了一大堆书，自己学习写作技巧。虽然他掌握了基本技能，但写出来的作文可能不合人意（太死板、太离题或缺乏深度）。  \n",
    "    2、RLHF就像老师给学生的作文打分、提供反馈：“这一段太啰嗦了”，“这个观点很好”，逐渐让学生明白什么样的作文更受欢迎。  \n",
    "    最终，这个学生不仅掌握了技术，还学会了如何更好地打动“老师”（用户），写出既合格又有感染力的文章。 \n",
    "```\n",
    "总结：用户需求高度主观或多样化的任务、安全性和可靠性要求高的任务、任务目标复杂且难以明确量化、需要动态优化的场景都**需要RLHF**"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0c79d35f",
   "metadata": {},
   "source": [
    "如果你的任务：\n",
    "1. **有明确目标和奖励函数的任务**  \n",
    "   - 对于可以清晰定义目标和奖励的任务，传统的强化学习或其他机器学习方法可能就足够了。  \n",
    "     - 机器人路径规划（目标是最短路径）。  \n",
    "     - 游戏 AI（如通过最高分数优化）。  \n",
    "\n",
    "2. **不需要高度人性化表现的任务**  \n",
    "   - 如果任务只要求模型执行具体计算或数据分析，而不涉及与用户交互或主观偏好。  \n",
    "     - 图像分类任务（如猫狗识别）。  \n",
    "     - 语音识别任务（将语音转化为文字）。  \n",
    "\n",
    "3. **应用场景对用户偏好不敏感**  \n",
    "   - 在一些领域，用户对 AI 的行为没有特别高的主观要求，模型只需按照明确的规则完成任务即可。    \n",
    "     - 数据清洗任务。  \n",
    "     - 财务报表的自动生成。  \n",
    "\n",
    "4. **资源和成本受限的场景**  \n",
    "   - RLHF 的训练需要大量人类反馈，涉及高成本和复杂性。如果任务需求对人类反馈依赖不高，可以选择更简单的优化方法。  \n",
    "     - 中小企业预算有限，开发一款标准化 AI 聊天机器人。  \n",
    "\n",
    "**RLHF 是否必要取决于任务的特点和目标：**  \n",
    "- **如果任务目标模糊、需要个性化、安全性高且对人类偏好敏感，RLHF 是非常需要的。**  \n",
    "- **如果任务明确、无需人性化表现，且已有成熟规则或奖励函数，RLHF 就不是必须的。**  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3ab21ca4",
   "metadata": {},
   "source": [
    "# 2.RLHF流程分解 "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eddcb882",
   "metadata": {},
   "source": [
    "## 2.1 RLHF核心流程"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "057602b0",
   "metadata": {},
   "source": [
    "RLHF 的过程可以分为三个主要阶段：  \n",
    "\n",
    "1. **预训练阶段**  \n",
    "使用大规模数据训练一个语言模型，让它学会语言的基本语法、语义和知识。这时候的模型虽然很强大，但回答可能会：  \n",
    "- 答非所问、不够自然或礼貌、输出危险或不适当的内容\n",
    "\n",
    "2. **奖励模型训练阶段（Reward Model Training）**  \n",
    "这时候引入了人类的反馈：  \n",
    "- 1. 模型生成一些回答（多个版本）。  \n",
    "- 2. 人类对这些回答进行评分或排序（比如哪个更好、哪个更差）。  \n",
    "- 3. 根据这些数据，训练一个 **奖励模型（Reward Model, RM）**，用来预测哪些回答更符合人类偏好。  \n",
    "\n",
    "3. **强化学习阶段（RL）**  \n",
    "利用 **强化学习**（如 PPO 算法），优化模型的生成策略：  \n",
    "- 奖励模型提供评分，模型调整自己的输出行为，生成更高分的回答。\n",
    "- 通过不断的试错和优化，模型最终能够生成更加优质和人性化的回答。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e2992779",
   "metadata": {},
   "source": [
    " 论文展示https://arxiv.org/pdf/2203.02155\n",
    "\n",
    "官网展示：https://openai.com/index/instruction-following/"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b3ea8cbc",
   "metadata": {},
   "source": [
    "<div align=center><img src=\"https://typora-photo1220.oss-cn-beijing.aliyuncs.com/DataAnalysis/muyan/image-20241208215307097.png\" width=100%></div>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "48cdc845",
   "metadata": {},
   "source": [
    "当前为翻译改版，方便大家阅读。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b2e23a2c",
   "metadata": {},
   "source": [
    "<div align=center><img src=\"https://typora-photo1220.oss-cn-beijing.aliyuncs.com/DataAnalysis/muyan/image-20241110181708019.png\" width=100%></div>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "94cc89e2",
   "metadata": {},
   "source": [
    "```json\n",
    "第一步：训练监督策略模型\n",
    "    从提示词数据集中取样一个提示词：首先，从包含各种提示词的数据集中随机选取一个提示词作为初始输入。\n",
    "    数据标记工程师给出期望的输出行为：然后，由人工标注员为这个提示词提供一个期望的故事内容或结构，这将作为模型的目标输出。\n",
    "    通过监督学习微调：接下来，使用监督学习的方法对模型进行微调，使其能够基于提供的提示词生成接近于预期结果的故事。\n",
    "第二步：训练奖励模型\n",
    "    取样一个提示词和模型多个输出：在这个阶段，再次从数据集抽取一个提示词，并让模型产生多个不同的故事版本。\n",
    "    数据标记工程师给出优劣排序：人工标注员会对这些不同版本的故事进行评估并按质量高低进行排序。\n",
    "    训练奖励模型：最后，用这些带有评分的故事样本去训练一个奖励模型，该模型学会预测哪些故事更符合人类的标准。\n",
    "第三步：采用近端策略优化进行强化学习\n",
    "    从提示词数据集取样一个新的提示词：继续从数据集中获取新的提示词作为下一个迭代的基础。\n",
    "    PPO模型由模型初始化：使用之前训练好的模型开始生成故事。\n",
    "    模型生成一个输出：模型尝试根据新提示词生成一个完整的故事。\n",
    "    奖励模型计算输出奖励值：接着，奖励模型会评价这个新生成的故事，并给出相应的分数。\n",
    "    利用PPO算法结合奖励更新策略：最后，通过PPO算法，结合奖励模型的反馈来调整模型的行为，使得它在未来能够生成更加高质量的故事。\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5c72885b",
   "metadata": {},
   "source": [
    "应用到 ChatGPT 的例子  \n",
    "\n",
    "1. **基础模型阶段（预训练）**  \n",
    "   - ChatGPT 学会生成语法正确的文本，但回答不一定符合你的期望。  \n",
    "   - 比如你问：“今天北京的天气怎么样？”  \n",
    "     - **初期模型回答**：可能会输出一堆天气概念或者乱答一通。  \n",
    "\n",
    "2. **人类反馈训练（奖励模型训练）**  \n",
    "   - 人类对模型的回答打分：  \n",
    "     - “回答清楚天气状况”得高分。  \n",
    "     - “答非所问”得低分。  \n",
    "   - 奖励模型学会预测用户更喜欢哪种回答。  \n",
    "\n",
    "3. **强化学习优化**  \n",
    "   - ChatGPT 开始通过试错生成回答，并根据奖励模型的评分不断优化。  \n",
    "     - 你再问：“今天北京的天气怎么样？”  \n",
    "     - **优化后回答**：  \n",
    "       - “今天北京的天气晴朗，气温在10-15℃之间，非常适合外出活动。”  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fff36aa3",
   "metadata": {},
   "source": [
    "<div align=center><img src=\"https://typora-photo1220.oss-cn-beijing.aliyuncs.com/DataAnalysis/muyan/image-20250319202340314.png\" width=100%></div>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3bf4d110",
   "metadata": {},
   "source": [
    "```json\n",
    "这就好比一个是一个大学生刚毕业，然后进入到一家企业开始实习，学习了基础专业知识后。开始使用各种方式来测试自己学到的技能，来方便更好的让自己进步，尽快达到能够独立成为王者的阶段。\n",
    "前边几节课已经通过使用lora的方式让模型如何学习某一个领域的知识。\n",
    "接下来就需要让模型反复训练自己能够在多种场景进行更好的回答(现在大模型强化学习阶段出现的算法组合方案层出不穷本次只简单列举三种)：\n",
    "    方案一：使用PPO+reward(奖励模型)组合成RLHF模式：就好比你这在学打篮球，不断练习投篮和过人技巧，并反复观看自己的练习视频每次进步一点点，并找教练指导、裁判来评分，边学边练。\n",
    "    方案二：使用DPO+reward(奖励模型)在网上下载一堆视频，不断学习别人好的技巧与坏的技巧，然后进行评判后学习。\n",
    "    方案三：仅仅使用DPO在网上下载一堆视频，不断学习别人好的技巧与坏的技巧，自我进行练习评判。\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d26d0c6d",
   "metadata": {},
   "source": [
    "## 2.2 数据收集"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "10b1490d",
   "metadata": {},
   "source": [
    "```json\n",
    "RLHF应用到GPT过程大致包括以下步骤：\n",
    "    1.收集人类反馈数据\n",
    "        让人类标注者根据模型生成的内容进行排序或评分，提供偏好信号。\n",
    "        数据形式通常是成对比较，例如：\n",
    "        回答A比回答B更有用、更准确或更安全。\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "97937afb",
   "metadata": {},
   "source": [
    "<div align=center><img src=\"https://typora-photo1220.oss-cn-beijing.aliyuncs.com/DataAnalysis/muyan/image-20241208220333711.png\" width=100%></div>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "26535420",
   "metadata": {},
   "source": [
    "<div align=center><img src=\"https://typora-photo1220.oss-cn-beijing.aliyuncs.com/DataAnalysis/muyan/image-20241208220352547.png\" width=100%></div>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3f86bd90",
   "metadata": {},
   "source": [
    "<div align=center><img src=\"https://typora-photo1220.oss-cn-beijing.aliyuncs.com/DataAnalysis/muyan/image-20241208220420119.png\" width=100%></div>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "766977ec",
   "metadata": {},
   "source": [
    "```json\n",
    "    2.训练奖励模型（Reward Model, RM）\n",
    "        使用人类反馈数据训练一个奖励模型，预测生成内容的质量评分。\n",
    "        奖励模型的目标是将人类偏好转化为机器可优化的奖励信号。\n",
    "\n",
    "    3.策略优化（Policy Optimization）\n",
    "        利用奖励模型的输出作为目标函数，训练语言模型。\n",
    "        具体方法是使用强化学习算法（如 PPO）微调 GPT 模型，使其生成的内容能够最大化奖励信号。\n",
    "    \n",
    "    4.持续优化与迭代\n",
    "        不断收集新的用户反馈和数据，更新奖励模型和策略优化的结果。\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "428dc8ec",
   "metadata": {},
   "source": [
    "# 3.RLHF框架详解"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a6a1d188",
   "metadata": {},
   "source": [
    "## 3.1 RLHF链路构成"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "79bc64a7",
   "metadata": {},
   "source": [
    "RLHF 主要由以下模型组成:\n",
    "\n",
    "1. Actor Model(动作模型)\n",
    "- 就是要优化的语言模型\n",
    "- 负责生成实际的文本回答\n",
    "- 参数会在训练过程中不断更新\n",
    "\n",
    "2. Reference Model(参考模型) \n",
    "- 是 Actor Model 的初始副本\n",
    "- 参数固定不变\n",
    "- 用于计算 KL 散度,防止 Actor 与初始模型偏离太远\n",
    "\n",
    "3. Reward Model(奖励模型)\n",
    "- 经过人类偏好训练的评分模型\n",
    "- 为 Actor 生成的文本提供奖励信号\n",
    "- 指导 Actor 向更好的方向优化\n",
    "\n",
    "4. Critic Model(评论家模型)\n",
    "- 用于估计价值函数\n",
    "- 预测动作的长期收益\n",
    "- 帮助 PPO 算法更好地优化 Actor"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fbadb6d0",
   "metadata": {},
   "source": [
    "模型间的交互流程:\n",
    "```json\n",
    "1. Actor Model 接收提示,生成回答\n",
    "   ↓\n",
    "2. Reward Model 评估回答质量,计算奖励\n",
    "   ↓\n",
    "3. Reference Model 计算与 Actor 的 KL 散度\n",
    "   ↓\n",
    "4. Critic Model 预测状态-动作价值\n",
    "   ↓\n",
    "5. PPO 使用这些信息更新 Actor Model\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d0415aec",
   "metadata": {},
   "source": [
    "<div align=center><img src=\"https://typora-photo1220.oss-cn-beijing.aliyuncs.com/DataAnalysis/muyan/image-20241203163522690.png\" width=100%></div>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c5aebe83",
   "metadata": {},
   "source": [
    "2. 它们是如何一起工作的:\n",
    "\n",
    "```json\n",
    "    Step 1: 生成阶段\n",
    "    用户: \"请解释 RLHF\"\n",
    "    ↓\n",
    "    Actor Model: 生成回答 \"RLHF 是...\"\n",
    "\n",
    "    Step 2: 评估阶段\n",
    "    Reward Model: 给回答打分 (比如 8 分)\n",
    "    Reference Model: 检查与原始模型的差异\n",
    "    Critic Model: 预测这个动作的价值\n",
    "\n",
    "    Step 3: 更新阶段\n",
    "    根据上述信息使用 PPO 更新 Actor Model\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "62c4dde4",
   "metadata": {},
   "source": [
    "**模型之间映射理解:**\n",
    "用滑雪的例子解释RLHF中各个模型的协作关系：\n",
    "\n",
    "1. 主要角色：\n",
    "```json\n",
    "    小明(Actor Model): 正在学习滑雪的学生\n",
    "    小明的录像带(Reference Model): 记录了小明最初的滑雪水平\n",
    "    裁判(Reward Model): 为每个动作打分的评判员\n",
    "    教练(Critic Model): 预判动作价值的指导者\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "781ff4e4",
   "metadata": {},
   "source": [
    "训练要求:    \n",
    "小明(Actor)是主角:\n",
    "- 在教练指导下训练\n",
    "- 根据裁判打分改进\n",
    "- 但始终受录像带约束\n",
    "- 每次动作都需要平衡:\n",
    "  - 追求高分\n",
    "  - 保持基本姿势\n",
    "  - 听从教练建议"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "14d4102b",
   "metadata": {},
   "source": [
    "<div align=center><img src=\"https://typora-photo1220.oss-cn-beijing.aliyuncs.com/DataAnalysis/muyan/image-20250319113534075.png\" width=100%></div>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "be9df32a",
   "metadata": {},
   "source": [
    "2. 训练过程的具体场景：\n",
    "\n",
    "起始状态:\n",
    "- 小明刚学会基本滑雪动作(预训练模型)\n",
    "- 录下了这个初始水平的录像(Reference Model)\n",
    "- 请来了专业裁判和教练(RM 和 Critic)\n",
    "\n",
    "每次训练循环:\n",
    "1. 小明看到斜坡(输入提示)\n",
    "2. 做出滑雪动作(生成回答)\n",
    "3. 裁判立即打分(即时奖励)\n",
    "4. 教练预测后续表现(价值评估)\n",
    "5. 对比录像带检查变化(KL 散度)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8588f4c1",
   "metadata": {},
   "source": [
    "3. 详细的互动过程：\n",
    "```json\n",
    "    第一轮训练:   \n",
    "    小明: \"我要这样滑下去...\"(准备动作)   \n",
    "    教练: \"这样可能得7分\"(预测价值)    \n",
    "    小明: *执行动作*    \n",
    "    裁判: \"8分!\"(即时奖励)    \n",
    "    工作人员: *对比录像带* \"动作变化在允许范围内\"(KL 检查)    \n",
    "```\n",
    "调整过程:\n",
    "- 如果动作偏离录像太多:\n",
    "  \"小明,别完全改变基本姿势\"(增加 KL 惩罚)\n",
    "  \n",
    "- 如果动作改进合适:\n",
    "  \"很好,保持这个改进方向\"(继续优化)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "49d902ca",
   "metadata": {},
   "source": [
    "4. 关键限制：\n",
    "\n",
    "- 小明每次训练都要和录像带对比\n",
    "- 不能和录像中的动作差异太大\n",
    "- 这个限制是永久性的,不会随训练轮数改变\n",
    "- 即使经过100次训练,也要控制和录像的差异"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "627b9cc9",
   "metadata": {},
   "source": [
    "5. 实际效果示例：\n",
    "```json\n",
    "    初始动作(录像带):\n",
    "    \"直直地滑下去\"\n",
    "\n",
    "    允许的渐进改进:\n",
    "    第1次: \"稍微弯曲膝盖滑下去\"\n",
    "    第2次: \"弯曲膝盖,身体稍微前倾\"\n",
    "    第3次: \"弯曲膝盖,前倾,手臂保持平衡\"\n",
    "\n",
    "    不允许的剧烈改变:\n",
    "    \"突然来个360度转体\"(与录像差异太大)\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8ef202f5",
   "metadata": {},
   "source": [
    "## 3.2 各模型输出"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "82de3809",
   "metadata": {},
   "source": [
    "1. 训练前准备：\n",
    "\n",
    "Reference Model(录像带):\n",
    "- 输入: 相同的滑雪场景\n",
    "- 输出: 生成动作的概率分布(用于后续计算 KL 散度)\n",
    "\n",
    "Reward Model(裁判)训练:\n",
    "- 输入: 大量人类标注的动作评分数据\n",
    "- 输出: 学会评判动作的好坏\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4648559a",
   "metadata": {},
   "source": [
    "2. 每轮训练循环：\n",
    "```python\n",
    "# 第一步：Actor 生成动作\n",
    "Actor(小明):\n",
    "    输入: 滑雪场景(prompt)\n",
    "    输出: 动作概率分布和具体动作\n",
    "    例如: {\n",
    "        \"向左转\": 0.7,\n",
    "        \"直滑\": 0.2,\n",
    "        \"向右转\": 0.1\n",
    "    }\n",
    "    最终选择: \"向左转\"\n",
    "\n",
    "# 第二步：Reference 生成概率\n",
    "Reference(录像带):\n",
    "    输入: 相同的滑雪场景\n",
    "    输出: 原始的动作概率分布\n",
    "    例如: {\n",
    "        \"向左转\": 0.3,\n",
    "        \"直滑\": 0.4,\n",
    "        \"向右转\": 0.3\n",
    "    }\n",
    "\n",
    "# 第三步：计算 KL 散度\n",
    "KL_divergence = compute_kl(\n",
    "    actor_probs={0.7, 0.2, 0.1},\n",
    "    reference_probs={0.3, 0.4, 0.3}\n",
    ")\n",
    "\n",
    "# 第四步：Reward Model 评分\n",
    "Reward Model(裁判):\n",
    "    输入: (滑雪场景, 小明的动作)\n",
    "    输出: 具体分数\n",
    "    例如: 8.5分\n",
    "\n",
    "# 第五步：Critic 预测\n",
    "Critic(教练):\n",
    "    输入: (滑雪场景, 小明的动作)\n",
    "    输出: 预期的长期价值\n",
    "    例如: 预测后续动作平均可得7.8分\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f8cef955",
   "metadata": {},
   "source": [
    "3. 更新阶段：\n",
    "```python\n",
    "    # PPO 更新\n",
    "    def update_actor():\n",
    "        advantage = reward - critic_value\n",
    "        # 如果 KL < 阈值:\n",
    "        if kl_divergence < max_kl:\n",
    "            if advantage > 0:  # 好的动作\n",
    "                # 增加该动作的概率\n",
    "                increase_action_probability()\n",
    "            else:  # 不好的动作\n",
    "                # 减少该动作的概率\n",
    "                decrease_action_probability()\n",
    "        \n",
    "        # 更新 Critic\n",
    "        critic_loss = (reward - critic_value)^2\n",
    "        update_critic(critic_loss)\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cadbf126",
   "metadata": {},
   "source": [
    "4. 一次完整的训练循环:    \n",
    "场景: \"陡峭的雪坡\"\n",
    "\n",
    "Actor 输出:\n",
    "- 动作概率: [0.7, 0.2, 0.1]\n",
    "- 选择动作: \"左转\"\n",
    "\n",
    "Reference 输出:\n",
    "- 动作概率: [0.3, 0.4, 0.3]\n",
    "\n",
    "KL 散度计算:\n",
    "- 结果: 0.45 (需要<0.5)\n",
    "\n",
    "Reward Model 输出:\n",
    "- 即时分数: 8.5\n",
    "\n",
    "Critic 输出:\n",
    "- 预期价值: 7.8\n",
    "\n",
    "最终更新:\n",
    "- 由于 KL<0.5 且 advantage>0（8.5-7.8=0.7）\n",
    "- 增加\"左转\"动作的概率\n",
    "- 更新 Critic 的预测能力\n",
    "\n",
    "优势值 = 实际得分 - 教练预测分\n",
    "例如：\n",
    "- 裁判实际打分：8分\n",
    "- 教练之前预测：7分\n",
    "- 优势值 = 8 - 7 = 1分(正值说明超出预期)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "edb3350a",
   "metadata": {},
   "source": [
    "# 4.奖励模型"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "66b0a5d7",
   "metadata": {},
   "source": [
    "## 4.1 训练奖励模型"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f2018296",
   "metadata": {},
   "source": [
    "**1. 数据收集阶段**\n",
    "\n",
    "A. 准备工作\n",
    "- 设计提示模板\n",
    "- 招募专业标注人员\n",
    "- 制定详细的评分标准\n",
    "\n",
    "B. 收集过程   \n",
    "提示示例: \"解释什么是机器学习\"\n",
    "\n",
    "模型生成多个回答:   \n",
    "回答A: \"机器学习是AI的一个分支,可以让计算机自动学习\"    \n",
    "回答B: \"机器学习是一种让计算机从数据中学习的方法。通过分析大量数据,计算机能够识别模式并做出预测\"   \n",
    "回答C: \"机器学习就是让机器变聪明的技术\"   \n",
    "\n",
    "人类标注:   \n",
    "- 评判标准: 准确性、完整性、清晰度   \n",
    "- 给出排序: B > A > C   \n",
    "- 记录原因: B更专业且详细,A基本正确但不够深入,C过于简单   \n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "100bd35f",
   "metadata": {},
   "source": [
    "**2. 数据处理阶段**\n",
    "\n",
    "A. 数据清洗\n",
    "- 删除矛盾的排序\n",
    "- 处理不一致的标注\n",
    "- 确保数据质量   \n",
    "\n",
    "B. 转换为训练样本   \n",
    "原始数据:\n",
    "- 提示P\n",
    "- 回答A、B、C\n",
    "- 排序B > A > C\n",
    "\n",
    "转换为配对形式:    \n",
    "样本1: (P, B, A) 标签: 1 (B更好)    \n",
    "样本2: (P, A, C) 标签: 1 (A更好)    \n",
    "样本3: (P, B, C) 标签: 1 (B更好)   "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8c86dbdc",
   "metadata": {},
   "source": [
    "**3. 模型构建**\n",
    "\n",
    "模型结构   \n",
    "- 基础: 预训练语言模型\n",
    "- 输入层: 处理(提示,回答)对\n",
    "- 中间层: 提取特征\n",
    "- 输出层: 单个分数\n",
    "\n",
    "保持不变的部分:\n",
    "- 所有的 Transformer 层\n",
    "- 词嵌入层\n",
    "- 位置编码\n",
    "- 注意力机制(也就是理解语言的所有能力)\n",
    "\n",
    "主要改造:\n",
    "- 仅改变最后的输出层\n",
    "- 从\"预测下一个词\"\n",
    "- 变成\"给出一个评分\"\n",
    "\n",
    "原始模型:   \n",
    "文本 -> Transformer层 -> 语言模型头 -> [词1概率,词2概率,词3概率...]\n",
    "\n",
    "Reward Model:   \n",
    "文本 -> Transformer层 -> 新全连接层 -> [单个分数]\n",
    "\n",
    "- 把一个\"会写作\"的模型\n",
    "- 改造成一个\"会打分\"的模型\n",
    "- 但保留了它理解语言的所有能力\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "48981b9e",
   "metadata": {},
   "source": [
    "**4. 训练过程**\n",
    "\n",
    "A. 初始化阶段\n",
    "- 加载预训练模型\n",
    "- 初始化新增参数\n",
    "- 设置学习率等超参数\n",
    "\n",
    "B. 训练循环\n",
    "每个批次:\n",
    "1. 读取批次数据\n",
    "   - 提示-回答对\n",
    "   - 人类排序标签\n",
    "\n",
    "2. 前向传播\n",
    "   - 输入提示和两个回答\n",
    "   - 分别计算两个回答的分数\n",
    "   - 计算分数差异\n",
    "\n",
    "3. 损失计算\n",
    "   例如: \n",
    "   - 回答B得分: 7.5\n",
    "   - 回答A得分: 5.8\n",
    "   - 确保分数差符合人类排序\n",
    "\n",
    "4. 反向传播\n",
    "   - 计算梯度\n",
    "   - 更新模型参数"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7cabedd5",
   "metadata": {},
   "source": [
    "## 4.2 学习打分\n",
    "\n",
    "1. 实际上，Reward Model 最初并不知道该给多少分    \n",
    "初始阶段:\n",
    "- 模型随机给分\n",
    "- 可能给好回答3分\n",
    "- 可能给差回答7分(完全不准确)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e5bf2804",
   "metadata": {},
   "source": [
    "2. 训练过程\n",
    "\n",
    "模型学习的是\"相对关系\":\n",
    "- 不是直接学习\"这个回答值6分\"\n",
    "- 而是学习\"A回答应该比B回答分数高\"\n",
    "\n",
    "核心目标：   \n",
    "让好回答的分数 > 差回答的分数\n",
    "\n",
    "例如：\n",
    "- 好回答(A)当前得7分\n",
    "- 差回答(B)当前得8分\n",
    "- 这违反了\"A应该>B\"的规则\n",
    "- 需要调整参数使 Score(A) > Score(B)\n",
    "\n",
    "参数调整过程   \n",
    "\n",
    "步骤1: 计算损失\n",
    "- 损失函数：-log(sigmoid(Score_A - Score_B))\n",
    "- 当 Score_A < Score_B 时，损失值大\n",
    "- 当 Score_A > Score_B 时，损失值小\n",
    "\n",
    "步骤2: 反向传播\n",
    "- 计算每个参数对损失的影响\n",
    "- 沿着减小损失的方向调整参数\n",
    "- 使 Score_A 变大，Score_B 变小\n",
    "\n",
    "例如：   \n",
    "第一轮：\n",
    "A(好回答): 3分\n",
    "B(差回答): 7分\n",
    "损失大 -> 调整参数\n",
    "\n",
    "第十轮：\n",
    "A(好回答): 5分\n",
    "B(差回答): 4分\n",
    "损失减小 -> 方向正确\n",
    "\n",
    "第五十轮：\n",
    "A(好回答): 8分\n",
    "B(差回答): 3分\n",
    "损失很小 -> 符合预期\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7a3c957d",
   "metadata": {},
   "source": [
    "关键点：\n",
    "- 具体分数(如6分还是7分)不是直接教的\n",
    "- 而是通过大量的\"比较学习\"自然形成的\n",
    "- 重要的是分数的相对关系,而不是绝对值"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "50eec4db",
   "metadata": {},
   "source": [
    "**reward停止**\n",
    "1. 损失值足够小 (如 < 0.01)\n",
    "2. 连续多轮损失不再明显下降\n",
    "3. 在验证集上的表现不再提升\n",
    "\n",
    "例如:\n",
    "```json\n",
    "轮次    损失值\n",
    "1       3.91\n",
    "10      1.52\n",
    "50      0.31\n",
    "100     0.05\n",
    "200     0.02\n",
    "300     0.019\n",
    "(当损失值趋于稳定时可以停止)\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2f654793",
   "metadata": {},
   "source": [
    "# 5.Critic model"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ddbff5b3",
   "metadata": {},
   "source": [
    "**1. 初始阶段**\n",
    "\n",
    "Critic 状态:\n",
    "- 随机初始化的小网络\n",
    "- 完全不会预测\n",
    "- 预测值与实际分数差距很大\n",
    "\n",
    "实际场景:   \n",
    "Actor: \"我要左转\"   \n",
    "Critic: \"我觉得可能得3分\"(随机预测)   \n",
    "Reward Model: \"实际得8分\"   \n",
    "Critic: \"记录下来,原来这种动作能得8分\"   \n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bd455749",
   "metadata": {},
   "source": [
    "**2. 学习阶段**\n",
    "\n",
    "早期学习:\n",
    "- 收集大量(动作,实际分数)的数据\n",
    "- 不断调整预测模型\n",
    "- 预测误差逐渐减小\n",
    "\n",
    "中期学习:\n",
    "- 开始掌握一些规律\n",
    "- 预测分数更接近实际\n",
    "- 可以给出较合理的预测\n",
    "\n",
    "后期学习:\n",
    "- 预测更准确稳定\n",
    "- 理解哪类动作分数更高\n",
    "- 能较好预测动作价值\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ce8cf03e",
   "metadata": {},
   "source": [
    "**3. 应用到 Actor 的过程**\n",
    "\n",
    "初期合作:\n",
    "- Critic 预测不准\n",
    "- Actor 主要依赖 Reward Model\n",
    "- Critic 在后台默默学习\n",
    "\n",
    "中期合作:\n",
    "Actor: \"我有两个选择,左转或直滑\"\n",
    "Critic: \"根据经验,左转可能得7分,直滑可能得5分\"\n",
    "Actor: \"那我选左转\"(参考 Critic 建议)\n",
    "\n",
    "成熟合作:\n",
    "- Critic 预测准确度高\n",
    "- Actor 更信任 Critic 的建议\n",
    "- 配合更默契"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4911276c",
   "metadata": {},
   "source": [
    "**4. 完整的训练循环**\n",
    "\n",
    "每轮训练:    \n",
    "1. Actor 面临选择    \n",
    "2. Critic 提供预测分数    \n",
    "3. Actor 参考预测做选择    \n",
    "4. Reward Model 给出实际分数    \n",
    "5. Critic 对比预测和实际分数   \n",
    "6. 更新自己的预测模型   \n",
    "7. 下一轮预测更准   "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7b545a36",
   "metadata": {},
   "source": [
    "示例:\n",
    "第一轮:\n",
    "- Critic 预测\"左转\"3分\n",
    "- 实际得8分\n",
    "- 学习调整预测模型\n",
    "\n",
    "第十轮:\n",
    "- Critic 预测\"左转\"6分\n",
    "- 实际得8分\n",
    "- 预测更准了\n",
    "\n",
    "第五十轮:\n",
    "- Critic 预测\"左转\"7.8分\n",
    "- 实际得8分\n",
    "- 预测已经很准确"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d50f5b35",
   "metadata": {},
   "source": [
    "# 6.RLHF与PPO"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "259c4435",
   "metadata": {},
   "source": [
    "**1.相同与不同**"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c975e5f4",
   "metadata": {},
   "source": [
    "RLHF可以看作是一个针对大语言模型的特殊PPO实现。\n",
    "\n",
    "相同点    \n",
    "核心机制:\n",
    "- 都使用价值估计\n",
    "- 都有策略限制\n",
    "- 都是迭代优化\n",
    "- 都用 Actor-Critic 架构\n",
    "\n",
    "不同点    \n",
    "1. 传统 PPO vs RLHF\n",
    "\n",
    "传统 PPO:\n",
    "- Actor: 执行动作的智能体\n",
    "- Critic: 评估状态价值\n",
    "- Reward: 预定义的奖励函数\n",
    "- Old Policy: 用于限制更新幅度\n",
    "\n",
    "RLHF:\n",
    "- Actor Model: 生成文本的模型\n",
    "- Critic Model: 预测长期价值\n",
    "- Reward Model: 评估文本质量\n",
    "- Reference Model: 限制模型偏离"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dc10eb67",
   "metadata": {},
   "source": [
    "\n",
    "**2. 主要区别**\n",
    "\n",
    "奖励来源:     \n",
    "传统PPO:\n",
    "- 每个动作都有即时奖励\n",
    "- 奖励明确定义\n",
    "\n",
    "RLHF改造:\n",
    "- 只有完整序列才有奖励\n",
    "- 奖励来自Reward Model\n",
    "- 需要处理奖励分配\n",
    "- 添加中间状态估计   \n",
    "\n",
    "状态空间:\n",
    "- PPO: 通常是明确的状态\n",
    "- RLHF: 是文本的语义空间\n",
    "\n",
    "动作空间   \n",
    "传统PPO:\n",
    "- 有限动作空间(如上下左右)\n",
    "- 每步动作独立\n",
    "- 即时知道好坏\n",
    "\n",
    "RLHF改造:\n",
    "- 处理50000+词表\n",
    "- 动作有上下文依赖\n",
    "- 使用重要性采样\n",
    "- 序列级别的决策\n",
    "\n",
    "3. 优化目标的改造\n",
    "\n",
    "传统PPO目标:\n",
    "- 最大化期望奖励\n",
    "- 简单的策略约束\n",
    "\n",
    "RLHF目标:\n",
    "- 最大化人类偏好奖励\n",
    "- KL散度约束(与参考模型)\n",
    "- 值函数损失\n",
    "- 多目标权重平衡"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "65e3dcff",
   "metadata": {},
   "source": [
    "## 6.1 转化为RL"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6f89f8ec",
   "metadata": {},
   "source": [
    "1. 一个具体的生成过程\n",
    "\n",
    "初始状态：    \n",
    "提示词 = \"请解释什么是AI\"   \n",
    "已生成 = \"\"   \n",
    "当前状态 = \"请解释什么是AI\"\n",
    "\n",
    "第一步选词：\n",
    "- 模型看到：\"请解释什么是AI\"\n",
    "- 需要选择第一个词\n",
    "- 可能的选择：[\"AI\", \"人工智能\", \"这个\"...]\n",
    "- 假设选择了：\"AI\"\n",
    "- 新状态变成：\"请解释什么是AI [SEP] AI\"\n",
    "\n",
    "第二步选词：\n",
    "- 模型看到：\"请解释什么是AI [SEP] AI\"\n",
    "- 需要选择第二个词\n",
    "- 可能的选择：[\"是\", \"指\", \"表示\"...]\n",
    "- 假设选择了：\"是\"\n",
    "- 新状态变成：\"请解释什么是AI [SEP] AI是\"\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "52536107",
   "metadata": {},
   "source": [
    "2. 每一步的决策过程\n",
    " \n",
    "模型在每一步都要：\n",
    "1. 看当前已有的所有文字\n",
    "2. 预测下一个词的概率\n",
    "3. 从这些概率中选一个词\n",
    "4. 把新词加到已生成的文字中\n",
    "5. 继续下一步\n",
    "\n",
    "就像玩文字接龙：\n",
    "- 每次只能加一个词\n",
    "- 要根据前面的内容决定下一个词\n",
    "- 直到生成完整的回答\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "df3cc9f7",
   "metadata": {},
   "source": [
    "3. 奖励是怎么给的\n",
    "```json\n",
    "输入：\n",
    "\"请解释什么是AI\"\n",
    "\n",
    "生成过程：\n",
    "Step 1: 选择\"AI\" \n",
    "        (状态: \"请解释什么是AI [SEP] AI\")\n",
    "        \n",
    "Step 2: 选择\"是\"\n",
    "        (状态: \"请解释什么是AI [SEP] AI是\")\n",
    "        \n",
    "Step 3: 选择\"一种\"\n",
    "        (状态: \"请解释什么是AI [SEP] AI是一种\")\n",
    "        \n",
    "... 直到生成结束\n",
    "\n",
    "最终回答：\n",
    "\"AI是一种模拟人类智能的技术\"\n",
    "\n",
    "获得奖励：\n",
    "Reward Model 评分：8分\n",
    "```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f829f460",
   "metadata": {},
   "source": [
    "**奖励模型介入时机**"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "929bbc5e",
   "metadata": {},
   "source": [
    "生成阶段:\n",
    "```json\n",
    "Actor: 生成完整回答\n",
    "↓\n",
    "评分阶段:\n",
    "Reward Model: 给出分数\n",
    "↓\n",
    "优化阶段:\n",
    "使用这个分数指导训练\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c3b41717",
   "metadata": {},
   "source": [
    "**RLHF整体示例**   \n",
    "提示: \"解释AI是什么\"\n",
    "\n",
    "步骤1: Actor生成回答   \n",
    "\"AI是一种模拟人类智能的技术\"\n",
    "\n",
    "步骤2: Reward Model评分\n",
    "- 输入: 提示+回答\n",
    "- 输出: 8分\n",
    "\n",
    "步骤3: Critic预测\n",
    "- 预测值: 6分\n",
    "- 计算优势: 8-6=2分(表现超出预期)\n",
    "\n",
    "步骤4: 更新Actor\n",
    "- 如果优势为正\n",
    "- 增加生成这样回答的概率"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "baee5d8b",
   "metadata": {},
   "source": [
    "## 6.2 KL散度应用"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f48e2ccf",
   "metadata": {},
   "source": [
    "1. 什么时候用 KL 散度\n",
    "\n",
    "在每次 Actor Model 更新前：\n",
    "- Actor要生成新回答\n",
    "- 在生成每个词时\n",
    "- 都要和Reference Model比较\n",
    "- 确保不会偏离太远\n",
    "\n",
    "例如：\n",
    "提示：\"解释AI\"   \n",
    "Reference: 倾向于平实的解释   \n",
    "Actor: 不能突然变成很花哨的解释   \n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bbcb31bc",
   "metadata": {},
   "source": [
    "2. 实际工作过程\n",
    "\n",
    "步骤1: 生成一个词之前\n",
    "- Reference看到：\"解释AI\"\n",
    "- Reference给出各个词的概率\n",
    "- Actor也给出各个词的概率\n",
    "- 对比两个概率的差异\n",
    "\n",
    "步骤2: 判断差异大小\n",
    "- 如果差异小：正常生成\n",
    "- 如果差异大：给予惩罚\n",
    "- 迫使Actor调整回来\n",
    "\n",
    "例如：\n",
    "Reference倾向于：\"AI是一种技术\"\n",
    "Actor突然想生成：\"AI乃是一种神奇的魔法\"\n",
    "系统会阻止这种大的改变\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "19b598e7",
   "metadata": {},
   "source": [
    "3. 具体判断方式\n",
    "\n",
    "每次生成时：\n",
    "1. 看两个模型给出的词的概率\n",
    "2. 如果概率差异大：\n",
    "   - 增加惩罚项\n",
    "   - 降低这种生成的可能\n",
    "\n",
    "例如：   \n",
    "\"AI\" 后面接什么词：   \n",
    "Reference: \"是\"(80%), \"表示\"(20%)   \n",
    "Actor: \"乃是\"(90%), \"是\"(10%)   \n",
    "→ 差异太大，需要纠正   "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e980b7ac",
   "metadata": {},
   "source": [
    "# 7.总结"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d74f7ef8",
   "metadata": {},
   "source": [
    "<div align=center><img src=\"https://typora-photo1220.oss-cn-beijing.aliyuncs.com/DataAnalysis/muyan/image-20250319164651451.png\" width=100%></div>"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "fufan_chat_api",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
